#include "..\Include\User.h"

wxString GenerateDBName()
{
    wxString str = wxEmptyString;
    static const wxString alphanum =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";

    for (int i = 0; i < mmDBNameLength; ++i)
    {
        str += alphanum[rand() % (alphanum.Length() ) ];
    }
    return str;
}

CUsers::CUsers(wxWindow* pParent, CMySqlWrapper* pMySql)
: m_pParent(pParent), m_pMySql(pMySql)
{

}

CUsers::~CUsers()
{

}

bool CUsers::GetNewUserInfo(wxWindow* pParent, SUserInfo& UserInfo, bool& RememberMe, const bool First)
{
    if (First)
    {
        wxString msg = wxString::Format(_("Welcome to %s!\n"), mmProgName);
        msg += _("I see that this is the first time you have run this program.\n");
        msg += _("Before you can begin, there are some things you need to do.  First\n");
        msg += _("you need to set up a User Account to be able to access your financial\n");
        msg += _("data.  This account will be the 'Master Account'.  It will enable\n");
        msg += _("you to control who has access to your finances by creating additional\n");
        msg += _("sub accounts, as well as how much others can access.  There are also\n");
        msg += _("other options that can only be accessed from this master account.\n");
        msg += _("Click 'OK' below to begin\n");
        mmMessageDlg(pParent, msg);
    }

    CNewUserDlg Dlg(pParent, UserInfo, RememberMe);
    if (Dlg.ShowModal() == wxID_CANCEL)
        return false;

    UserInfo.DefaultDBName = GenerateDBName();
    return true;
}

bool CUsers::CheckIfUserNameExists(wxString UserName)
{
    wxString Query = wxString::Format("SELECT col_UserName, COUNT(*) FROM %s.tab_Users WHERE %s.tab_Users.col_UserName=\"%s\"",
                                      mmSharedDBName, mmSharedDBName, UserName);
    if (!m_pMySql->RunQuery(Query) )
        mmErrorDlg(this, m_pMySql->GetLastError() );
    MYSQL_ROW row = m_pMySql->GetNextRowFromResultSet();
    if (row[0] == NULL)
        // user name does NOT exist
        return false;

    // user name DOES exist
    mmMessageDlg(this, wxString::Format("User name '%s' is aready being used.\nPlease select another user name.",
                                        UserName) );
    return true;
}

bool CUsers::SaveUser(SUserInfo& UI, const bool IsNewUser, const bool IsFirstUser)
{
    if (IsFirstUser)
    {
        if (!mm::CreateCustomDatabase(m_pMySql, UI.DefaultDBName) )
        {
            mmErrorDlg(this, m_pMySql->GetLastError() );
            return false;
        }
    }

    wxString Query;
    (IsNewUser) ? Query = "INSERT INTO " : Query = "UPDATE ";
    Query += wxString::Format("`%s`.`tab_Users` SET ", mmSharedDBName);
    Query += wxString::Format("col_FirstName='%s',", UI.FirstName);
    Query += wxString::Format("col_LastName='%s',", UI.LastName);
    Query += wxString::Format("col_UserName='%s',", UI.UserName);
    Query += wxString::Format("col_Password='%s',", UI.Password);
    Query += wxString::Format("col_DefaultDBName='%s'", UI.DefaultDBName);
    if (!IsNewUser)
    {
        Query += wxString::Format(" WHERE col_UserName='%s'", UI.UserName);
    }
    if (!m_pMySql->RunQuery(Query) )
    {
        mmErrorDlg(this, wxString::Format("Could not save user\n%s",
                                          m_pMySql>GetLastError() ) );
        return false;
    }

    return true;
}

bool CUsers::LogInUser(const SUserInfo& UserInfo, const bool CheckUserID)
{
    m_CurrentUser = UserInfo;
    int attempt = 1;
    bool SaveInfo = false;
    wxString UserName;
    wxString Password;
    if (!CheckUserID)
    {
        UserName = m_CurrentUser.UserName;
        Password = m_CurrentUser.Password;
    }
    else
    {
        UserName = mm::g_pOptions->LOGIN.DefaultUserName;
        Password = mm::g_pOptions->LOGIN.DefaultPassword;
    }

    do
    {
        if (UserName == wxEmptyString || Password == wxEmptyString)
        {
            CLogInDlg Dlg( (wxWindow*)this, UserName, Password, SaveInfo);
            if (Dlg.ShowModal() == wxID_CANCEL)
            {
                return false;
            }
        }

        wxString Query = wxString::Format("SELECT * FROM %s.tab_Users WHERE col_UserName='%s'",
                                          mmSharedDBName,
                                          UserName);
        if (!m_pMySql->RunQuery(Query) )
        {
            mmErrorDlg(this, wxString::Format("MySQL Query failed\n%s\n%s", Query, m_pMySql->GetLastError() ) );
            return false;
        }

        MYSQL_ROW row = m_pMySql->GetNextRowFromResultSet();
        if (!row)
            return false;

        if (UserName == (wxString)row[2] && Password == (wxString)row[3] )
        {
            m_CurrentUser.FirstName     = (wxString)row[0];
            m_CurrentUser.LastName      = (wxString)row[1];
            m_CurrentUser.UserName      = (wxString)row[2];
            m_CurrentUser.Password      = (wxString)row[3];
            m_CurrentUser.DefaultDBName = (wxString)row[4];
            if (SaveInfo)
            {
                mm::g_pOptions->LOGIN.DefaultUserName = m_CurrentUser.UserName;
                mm::g_pOptions->LOGIN.DefaultPassword = m_CurrentUser.Password;
            }
            m_pMySql->SetDefaultDatabase(m_CurrentUser.DefaultDBName);
            return true;
        }
        else
        {
            mmMessageDlg(this, _("Incorrect User Name and/or Password\n") );
            UserName = wxEmptyString;
            Password = wxEmptyString;
            attempt++;
        }
    } while (attempt < 3);

    mmMessageDlg(this, _("Maximum number of login attempts exceeded!") );
    return false;
}

const SUserInfo CUsers::GetCurrentUser() const
{
    return m_CurrentUser;
}

void CUsers::SetCurrentUser(const SUserInfo& UI)
{
    m_CurrentUser = UI;
}

